﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using System.Web.UI;
using System.Web.UI.HtmlControls;

using DotNetNuke.Entities.Modules;
using DesertedRoadStudios.BlogNetNuke.Common;
using DesertedRoadStudios.BlogNetNuke.Components;

namespace DesertedRoadStudios.BlogNetNuke.UI
{
    public class Blog : PortalModuleBase
    {
        private int _portalID;
        private int _moduleID;
        private int _tabID;
        private XDocument _settings;
        private string _previousURL = string.Empty;
        private string _nextURL = string.Empty;

        public string PreviousURL { get { return _previousURL; } }
        public string NextURL { get { return _nextURL; } }
        
        public Blog()
        {
        }

        public Blog(int portalID, int moduleID, int tabID, XDocument settings)
        {
            _portalID = portalID;
            _moduleID = moduleID;
            _tabID = tabID;
            _settings = settings;
        }

        protected void Page_PreRender(object sender, EventArgs e)
        {
            if (_settings.Element("params").Element("RequestType").Value.Equals(RequestType.CategoryView.ToString()))
            {
                Page.Title = "All posts categorized under '" + _settings.Element("params").Element("Category").Value.Replace("-", " ") + "'";

                /*
                BlogNetNukeController bnn = new BlogNetNukeController();
                IEnumerable<CategoryInfo> categories = bnn.GetCategories(Convert.ToInt32(_settings.Element("params").Element("Blog").Element("BlogDetails").Element("PortalID").Value), Convert.ToInt32(_settings.Element("params").Element("Blog").Element("BlogDetails").Element("ModuleID").Value));
                CategoryInfo category = categories.Where(c => c.Slug.ToLower().Equals(_settings.Element("params").Element("Category").Value.ToLower())).SingleOrDefault();

                if (category != null)
                {
                    if (!string.IsNullOrEmpty(category.Description))
                    {
                        ((HtmlMeta)Page.Header.FindControl("MetaDescription")).Visible = true;
                        ((HtmlMeta)Page.Header.FindControl("MetaDescription")).Content = category.Description;
                    }

                    if (!string.IsNullOrEmpty(category.Keywords))
                    {
                        ((HtmlMeta)Page.Header.FindControl("MetaKeywords")).Visible = true;
                        ((HtmlMeta)Page.Header.FindControl("MetaKeywords")).Content = category.Keywords;
                    }
                }
                */
            }
            else if (_settings.Element("params").Element("RequestType").Value.Equals(RequestType.TagView.ToString()))
                Page.Title = "All posts tagged '" + _settings.Element("params").Element("Tag").Value.Replace("-", " ") + "'";
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            BlogNetNukeController bnn = new BlogNetNukeController();
            HtmlControl contentPane = FindControl("ContentPane") as HtmlControl;

            if (_settings.Element("params").Element("RequestType").Value.Equals(RequestType.PostView.ToString()))
            {
                // If Post Status is "Deleted" then redirect to Blog home
                if (_settings.Element("params").Element("Post").Element("PostDetails").Element("Status").Value.Equals(Enum.GetName(typeof(PostStatus), PostStatus.Deleted)))
                    Response.Redirect(_settings.Element("params").Element("Blog").Element("BlogDetails").Element("AbsoluteURL").Value, true);
             
                // If Post Status is "Draft" or "Pending Review" and User is not an Admin, then redirect to Blog home
                if ((_settings.Element("params").Element("Post").Element("PostDetails").Element("Status").Value.Equals(Enum.GetName(typeof(PostStatus), PostStatus.Draft)) ||
                    _settings.Element("params").Element("Post").Element("PostDetails").Element("Status").Value.Equals(Enum.GetName(typeof(PostStatus), PostStatus.PendingReview)) ||
                   (Convert.ToDateTime(_settings.Element("params").Element("Post").Element("PostDetails").Element("PublishedDate").Value) > DateTime.Now)) &&
                   !UserInfo.IsSuperUser)
                    Response.Redirect(_settings.Element("params").Element("Blog").Element("BlogDetails").Element("AbsoluteURL").Value, true);

                
                object[] parameters = { _portalID, _moduleID, _settings.Element("params").Element("Post").Element("PostDetails").Element("PostPath").Value };
                UserControl postControl = Page.LoadControl(_settings.Element("params").Element("Settings").Element("PostsViewContainerControl").Value, parameters);

                // Hide Pagenation
                HtmlControl cntrlPrev = FindControl("PreviousContentPane") as HtmlControl;
                if (cntrlPrev != null)
                    cntrlPrev.Visible = false;

                HtmlControl cntrlNext = FindControl("NextContentPane") as HtmlControl;
                if (cntrlNext != null)
                    cntrlNext.Visible = false;

                // Load Comments
                HtmlControl commentsPane = postControl.FindControl("CommentsPane") as HtmlControl;

                if (commentsPane != null)
                {
                    if (Convert.ToBoolean(_settings.Element("params").Element("Post").Element("PostDetails").Element("AllowComments").Value))
                    {
                        if (_settings.Element("params").Element("Settings").Elements().Where(d => d.Name == "CommentsViewContainerControl").Any() &&
                            !string.IsNullOrEmpty(_settings.Element("params").Element("Settings").Element("CommentsViewContainerControl").Value))
                        {
                            IEnumerable<CommentInfo> comments;

                            if (UserInfo.IsSuperUser)
                                comments = bnn.GetAllCommentsForPost(_portalID, _moduleID, new Guid(_settings.Element("params").Element("Post").Element("PostDetails").Element("PostID").Value)).Where(c => c.IsDeleted == false);
                            else
                                comments = bnn.GetAllCommentsForPost(_portalID, _moduleID, new Guid(_settings.Element("params").Element("Post").Element("PostDetails").Element("PostID").Value)).Where(c => (c.IsDeleted == false) && (c.IsApproved == true));

                            int i = 0;
                            foreach (CommentInfo comment in comments)
                            {
                                object[] commentParams = { comment, Convert.ToInt32(_settings.Element("params").Element("Post").Element("PostDetails").Element("TotalComments").Value), i, _settings.Element("params").Element("Post").Element("PostDetails").Element("RelativeURL").Value };
                                UserControl commentsControl = Page.LoadControl(_settings.Element("params").Element("Settings").Element("CommentsViewContainerControl").Value, commentParams);
                                if (!comment.IsApproved)
                                    commentsPane.Controls.Add(new LiteralControl("<div style=\"border:3px dashed #f00;margin-top:10px;margin-bottom:10px;\">"));

                                commentsPane.Controls.Add(commentsControl);

                                if (!comment.IsApproved)
                                    commentsPane.Controls.Add(new LiteralControl("</div>"));

                                i++;
                            }
                        }
                        else
                        {
                            commentsPane.Controls.Add(new LiteralControl("<strong style=\"color:#f00;\">A container control has not been configured for the comments.  Please check module configuration.</strong><br /><br />"));
                        }

                        // Load Comment Form
                        HtmlControl commentsFormPane = postControl.FindControl("CommentsFormPane") as HtmlControl;

                        if (commentsFormPane != null)
                        {
                            if (_settings.Element("params").Element("Settings").Elements().Where(d => d.Name == "CommentsFormContainerControl").Any() &&
                                !string.IsNullOrEmpty(_settings.Element("params").Element("Settings").Element("CommentsFormContainerControl").Value))
                            {
                                object[] commentsFormParams = { true };
                                UserControl commentsFormControl = Page.LoadControl(_settings.Element("params").Element("Settings").Element("CommentsFormContainerControl").Value, commentsFormParams);
                                commentsFormPane.Controls.Add(commentsFormControl);
                            }
                            else
                            {
                                commentsFormPane.Controls.Add(new LiteralControl("<strong style=\"color:#f00;\">A container control has not been configured for the comments form.  Please check module configuration.</strong><br /><br />"));
                            }
                        }
                    }
                    else
                    {
                        commentsPane.Visible = false;

                        HtmlControl commentsFormPane = postControl.FindControl("commentsFormPane") as HtmlControl;
                        if (commentsFormPane != null)
                            commentsFormPane.Visible = false;
                    }
                }

                contentPane.Controls.Add(postControl);
            }
            else
            {
                IEnumerable<PostInfo> posts = null;
                int page = 0;
                int perPage = Convert.ToInt32(_settings.Element("params").Element("Settings").Element("PostsPerPage").Value);
                int max = perPage;

                if (_settings.Element("params").Element("RequestType").Value.Equals(RequestType.FullView.ToString()))
                {
                    if (UserInfo.IsSuperUser)
                        posts = bnn.GetAllPosts(_portalID, _moduleID, _tabID).Where(p =>
                                    p.Status != PostStatus.Deleted);
                    else
                        posts = bnn.GetAllPosts(_portalID, _moduleID, _tabID).Where(p =>
                                    p.Status == PostStatus.Published);
                }
                else if (_settings.Element("params").Element("RequestType").Value.Equals(RequestType.YearView.ToString()))
                {
                    if (UserInfo.IsSuperUser)
                        posts = bnn.GetAllPosts(_portalID, _moduleID, _tabID).Where(p =>
                                    p.PublishedDate.Year.ToString().Equals(_settings.Element("params").Element("Year").Value) &&
                                    p.Status != PostStatus.Deleted);
                    else
                        posts = bnn.GetAllPosts(_portalID, _moduleID, _tabID).Where(p =>
                                    p.PublishedDate.Year.ToString().Equals(_settings.Element("params").Element("Year").Value) &&
                                    p.Status == PostStatus.Published);
                }
                else if (_settings.Element("params").Element("RequestType").Value.Equals(RequestType.MonthView.ToString()))
                {
                    if (UserInfo.IsSuperUser)
                        posts = bnn.GetAllPosts(_portalID, _moduleID, _tabID).Where(p =>
                                    p.PublishedDate.Year.ToString().Equals(_settings.Element("params").Element("Year").Value) &&
                                    p.PublishedDate.ToString("MM").Equals(_settings.Element("params").Element("Month").Value) &&
                                    p.Status != PostStatus.Deleted);
                    else
                        posts = bnn.GetAllPosts(_portalID, _moduleID, _tabID).Where(p =>
                                    p.PublishedDate.Year.ToString().Equals(_settings.Element("params").Element("Year").Value) &&
                                    p.PublishedDate.ToString("MM").Equals(_settings.Element("params").Element("Month").Value) &&
                                    p.Status == PostStatus.Published);
                }
                else if (_settings.Element("params").Element("RequestType").Value.Equals(RequestType.DayView.ToString()))
                {
                    if (UserInfo.IsSuperUser)
                        posts = bnn.GetAllPosts(_portalID, _moduleID, _tabID).Where(p =>
                                    p.PublishedDate.Year.ToString().Equals(_settings.Element("params").Element("Year").Value) &&
                                    p.PublishedDate.ToString("MM").Equals(_settings.Element("params").Element("Month").Value) &&
                                    p.PublishedDate.ToString("dd").Equals(_settings.Element("params").Element("Day").Value) &&
                                    p.Status != PostStatus.Deleted);
                    else
                        posts = bnn.GetAllPosts(_portalID, _moduleID, _tabID).Where(p =>
                                    p.PublishedDate.Year.ToString().Equals(_settings.Element("params").Element("Year").Value) &&
                                    p.PublishedDate.ToString("MM").Equals(_settings.Element("params").Element("Month").Value) &&
                                    p.PublishedDate.ToString("dd").Equals(_settings.Element("params").Element("Day").Value) &&
                                    p.Status == PostStatus.Published);
                }
                else if (_settings.Element("params").Element("RequestType").Value.Equals(RequestType.CategoryView.ToString()))
                {
                    if (UserInfo.IsSuperUser)
                        posts = bnn.GetAllPostsForCategory(_portalID, _moduleID, _settings.Element("params").Element("Category").Value).Where(p=>
                                    p.Status != PostStatus.Deleted);
                    else
                        posts = bnn.GetAllPostsForCategory(_portalID, _moduleID, _settings.Element("params").Element("Category").Value).Where(p =>
                                    p.Status == PostStatus.Published);
                }
                else if (_settings.Element("params").Element("RequestType").Value.Equals(RequestType.TagView.ToString()))
                {
                    if (UserInfo.IsSuperUser)
                        posts = bnn.GetAllPostsForTag(_portalID, _moduleID, _settings.Element("params").Element("Tag").Value).Where(p =>
                                    p.Status != PostStatus.Deleted);
                    else
                        posts = bnn.GetAllPostsForTag(_portalID, _moduleID, _settings.Element("params").Element("Tag").Value).Where(p =>
                                    p.Status == PostStatus.Published);
                }

                //if (!_settings.Element("params").Element("RequestType").Value.Equals(RequestType.TagView.ToString()))
                //Controls.Add(new LiteralControl(_settings.ToString()));
                //Controls.Add(new LiteralControl("<br /><br />" + posts.Count().ToString()));
                //Controls.Add(new LiteralControl("<br /><br />" + Request.Url.ToString()));
                
                try
                {
                    if (Request.QueryString["Page"] != null)
                        page = Convert.ToInt32(Request.QueryString["Page"]) - 1;
                    else
                        page = 0;
                }
                catch
                {
                    page = 0;
                }

                int totalCount = posts.Count();

                if (page < 0)
                    page = 0;
                else if (page * perPage >= totalCount)
                    page = Convert.ToInt32(Math.Truncate((decimal)(totalCount / perPage))) - 1;

                if (totalCount < max)
                    max = totalCount;
                else if (perPage * (page + 1) > totalCount)
                    max = totalCount - (perPage * page);
                
                // Construct base URL for prev and next links
                StringBuilder baseLinkURL = new StringBuilder();
                baseLinkURL.Append(_settings.Element("params").Element("Blog").Element("BlogDetails").Element("TabPath").Value.Replace("//", "/"));

                switch (_settings.Element("params").Element("RequestType").Value)
                {
                    case "YearView":
                        baseLinkURL.Append("/" + _settings.Element("params").Element("Year").Value);
                        break;
                    case "MonthView":
                        baseLinkURL.Append("/" + _settings.Element("params").Element("Year").Value + "/");
                        baseLinkURL.Append(_settings.Element("params").Element("Month").Value);
                        break;
                    case "DayView":
                        baseLinkURL.Append("/" + _settings.Element("params").Element("Year").Value + "/");
                        baseLinkURL.Append(_settings.Element("params").Element("Month").Value + "/");
                        baseLinkURL.Append(_settings.Element("params").Element("Day").Value);
                        break;
                    case "CategoryView":
                        baseLinkURL.Append("/Category/" + _settings.Element("params").Element("Category").Value);
                        break;
                    case "TagView":
                        baseLinkURL.Append("/Tag/" + _settings.Element("params").Element("Tag").Value);
                        break;
                }

                // Check should we display a previous page link
                HtmlControl cntrlPrev = FindControl("PreviousContentPane") as HtmlControl;
                if (cntrlPrev != null)
                {
                    if (page > 0)
                        _previousURL = Methods.GetPathExtension(_settings, baseLinkURL.ToString()) + "?Page=" + page.ToString();
                    else
                        cntrlPrev.Visible = false;
                }
                
                // Check should we display a next page link
                HtmlControl cntrlNext = FindControl("NextContentPane") as HtmlControl;
                if (cntrlNext != null)
                {
                    if (totalCount - (perPage * (page + 1)) > 0)
                        _nextURL = Methods.GetPathExtension(_settings, baseLinkURL.ToString()) + "?Page=" + (page + 2).ToString();
                    else
                        cntrlNext.Visible = false;
                }

                foreach (PostInfo post in posts.Skip(page * perPage).Take(max))
                {
                    object[] parameters = { _portalID, _moduleID, post.PostID };
                    UserControl control = Page.LoadControl(_settings.Element("params").Element("Settings").Element("PostsListContainerControl").Value, parameters);
                    contentPane.Controls.Add(control);
                }
            }
        }
    }
}